home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / relief.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  23KB  |  803 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/relief.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************
  8.  
  9.     Playfield encoding
  10.     ------------------
  11.         1 16-bit word is used
  12.  
  13.         Word 1:
  14.             Bits 13-15 = palette
  15.             Bits  0-12 = image number
  16.  
  17.  
  18.     Motion Object encoding
  19.     ----------------------
  20.         4 16-bit words are used
  21.  
  22.         Word 1:
  23.             Bits  0-7  = link to the next motion object
  24.  
  25.         Word 2:
  26.             Bits  0-11 = image index
  27.  
  28.         Word 3:
  29.             Bits  7-15 = horizontal position
  30.             Bits  0-3  = motion object palette
  31.  
  32.         Word 4:
  33.             Bits  7-15 = vertical position
  34.             Bits  4-6  = horizontal size of the object, in tiles
  35.             Bit   3    = horizontal flip
  36.             Bits  0-2  = vertical size of the object, in tiles
  37.  
  38.  
  39.     Alpha layer encoding
  40.     --------------------
  41.         1 16-bit word is used
  42.  
  43.         Word 1:
  44.             Bit  15    = transparent/opaque
  45.             Bit  10-13 = color
  46.             Bits  0-9  = index of the character
  47.  
  48. ***************************************************************************/
  49.  
  50. #include "driver.h"
  51. #include "machine/atarigen.h"
  52. #include "vidhrdw/generic.h"
  53.  
  54. #define XCHARS 42
  55. #define YCHARS 30
  56.  
  57. #define XDIM (XCHARS*8)
  58. #define YDIM (YCHARS*8)
  59.  
  60.  
  61. #define DEBUG_VIDEO 0
  62.  
  63.  
  64.  
  65. /*************************************
  66.  *
  67.  *    Structures
  68.  *
  69.  *************************************/
  70.  
  71. struct pf_overrender_data
  72. {
  73.     struct osd_bitmap *bitmap;
  74.     int mo_priority;
  75. };
  76.  
  77.  
  78.  
  79. /*************************************
  80.  *
  81.  *    Statics
  82.  *
  83.  *************************************/
  84.  
  85. static struct atarigen_pf_state pf_state;
  86. static struct atarigen_pf_state pf2_state;
  87.  
  88. #if DEBUG_VIDEO
  89. static int show_colors;
  90. static int special_pen;
  91. #endif
  92.  
  93.  
  94.  
  95. /*************************************
  96.  *
  97.  *    Prototypes
  98.  *
  99.  *************************************/
  100.  
  101. static const UINT8 *update_palette(void);
  102.  
  103. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  104. static void pf2_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  105. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  106. static void pf2_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  107. static void pf2_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  108.  
  109. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  110. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  111.  
  112. #if DEBUG_VIDEO
  113. static void debug(void);
  114. #endif
  115.  
  116.  
  117.  
  118. /*************************************
  119.  *
  120.  *    Video system start
  121.  *
  122.  *************************************/
  123.  
  124. int relief_vh_start(void)
  125. {
  126.     static struct atarigen_mo_desc mo_desc =
  127.     {
  128.         256,                 /* maximum number of MO's */
  129.         8,                   /* number of bytes per MO entry */
  130.         2,                   /* number of bytes between MO words */
  131.         0,                   /* ignore an entry if this word == 0xffff */
  132.         0, 0, 0xff,          /* link = (data[linkword] >> linkshift) & linkmask */
  133.         0                    /* reverse order */
  134.     };
  135.  
  136.     static struct atarigen_pf_desc pf_desc =
  137.     {
  138.         8, 8,                /* width/height of each tile */
  139.         64, 64                /* number of tiles in each direction */
  140.     };
  141.     
  142.     /* reset statics */
  143.     memset(&pf_state, 0, sizeof(pf_state));
  144.     memset(&pf2_state, 0, sizeof(pf2_state));
  145.     
  146.     /* initialize the playfield */
  147.     if (atarigen_pf_init(&pf_desc))
  148.         return 1;
  149.     
  150.     /* initialize the second playfield */
  151.     if (atarigen_pf2_init(&pf_desc))
  152.     {
  153.         atarigen_pf_free();
  154.         return 1;
  155.     }
  156.     
  157.     /* initialize the motion objects */
  158.     if (atarigen_mo_init(&mo_desc))
  159.     {
  160.         atarigen_pf2_free();
  161.         atarigen_pf_free();
  162.         return 1;
  163.     }
  164.     
  165.     return 0;
  166. }
  167.  
  168.  
  169.  
  170. /*************************************
  171.  *
  172.  *    Video system shutdown
  173.  *
  174.  *************************************/
  175.  
  176. void relief_vh_stop(void)
  177. {
  178.     atarigen_pf2_free();
  179.     atarigen_pf_free();
  180.     atarigen_mo_free();
  181. }
  182.  
  183.  
  184.  
  185. /*************************************
  186.  *
  187.  *    Playfield RAM write handlers
  188.  *
  189.  *************************************/
  190.  
  191. WRITE_HANDLER( relief_colorram_w )
  192. {
  193.     int oldword = READ_WORD(&atarigen_playfieldram_color[offset]);
  194.     int newword = COMBINE_WORD(oldword, data);
  195.  
  196.     /* only update if changed */
  197.     if (oldword != newword)
  198.     {
  199.         WRITE_WORD(&atarigen_playfieldram_color[offset], newword);
  200.         
  201.         oldword ^= newword;
  202.         
  203.         /* low byte affects pf1 */
  204.         if (oldword & 0x00ff)
  205.             atarigen_pf_dirty[(offset / 2) & 0xfff] = 1;
  206.  
  207.         /* upper byte affects pf2 */
  208.         if (oldword & 0xff00)
  209.             atarigen_pf2_dirty[(offset / 2) & 0xfff] = 1;
  210.     }
  211. }
  212.  
  213.  
  214. WRITE_HANDLER( relief_playfieldram_w )
  215. {
  216.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  217.     int newword = COMBINE_WORD(oldword, data);
  218.  
  219.     /* only update if changed */
  220.     if (oldword != newword)
  221.     {
  222.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  223.         atarigen_pf_dirty[(offset / 2) & 0xfff] = 1;
  224.     }
  225.     
  226.     /* handle the latch, but only write the lower byte */
  227.     if (atarigen_video_control_state.latch2 != -1)
  228.         relief_colorram_w(offset, atarigen_video_control_state.latch2 | 0xff000000);
  229. }
  230.  
  231.  
  232. WRITE_HANDLER( relief_playfield2ram_w )
  233. {
  234.     int oldword = READ_WORD(&atarigen_playfield2ram[offset]);
  235.     int newword = COMBINE_WORD(oldword, data);
  236.  
  237.     /* only update if changed */
  238.     if (oldword != newword)
  239.     {
  240.         WRITE_WORD(&atarigen_playfield2ram[offset], newword);
  241.         atarigen_pf2_dirty[(offset / 2) & 0xfff] = 1;
  242.     }
  243.     
  244.     /* handle the latch, but only write the upper byte */
  245.     if (atarigen_video_control_state.latch1 != -1)
  246.         relief_colorram_w(offset, atarigen_video_control_state.latch1 | 0x00ff0000);
  247. }
  248.  
  249.  
  250.  
  251. /*************************************
  252.  *
  253.  *    Periodic scanline updater
  254.  *
  255.  *************************************/
  256.  
  257. void relief_scanline_update(int scanline)
  258. {
  259.     /* update the playfield */
  260.     if (scanline == 0)
  261.     {
  262.         atarigen_video_control_update(&atarigen_alpharam[0xf00]);
  263.  
  264.         /* copy in the scroll values */
  265.         pf_state.hscroll = atarigen_video_control_state.pf1_xscroll + (atarigen_video_control_state.pf2_xscroll & 7);
  266.         pf_state.vscroll = atarigen_video_control_state.pf1_yscroll;
  267.         pf2_state.hscroll = atarigen_video_control_state.pf2_xscroll + 4;
  268.         pf2_state.vscroll = atarigen_video_control_state.pf2_yscroll;
  269.         
  270.         /* update the two playfields */
  271.         atarigen_pf_update(&pf_state, scanline);
  272.         atarigen_pf2_update(&pf2_state, scanline);
  273.     }
  274.  
  275.     /* update the MOs from the SLIP table */
  276.     atarigen_mo_update_slip_512(atarigen_spriteram, atarigen_video_control_state.sprite_yscroll, scanline, &atarigen_alpharam[0xf80]);
  277. }
  278.  
  279.  
  280.  
  281. /*************************************
  282.  *
  283.  *    Main refresh
  284.  *
  285.  *************************************/
  286.  
  287. void relief_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  288. {
  289.     int i;
  290.     
  291. #if DEBUG_VIDEO
  292.     debug();
  293. #endif
  294.  
  295.     /* update the palette */
  296.     if (update_palette())
  297.     {
  298.         memset(atarigen_pf_dirty, 1, atarigen_playfieldram_size / 2);
  299.         memset(atarigen_pf2_dirty, 1, atarigen_playfield2ram_size / 2);
  300.     }
  301.  
  302.     /* set up the all-transparent overrender palette */
  303.     for (i = 0; i < 16; i++)
  304.         atarigen_overrender_colortable[i] = palette_transparent_pen;
  305.  
  306.     /* render the playfield */
  307.     memset(atarigen_pf_visit, 0, 64*64);
  308. #if DEBUG_VIDEO
  309.     if (show_colors == 2)
  310.         osd_clearbitmap(bitmap);
  311.     else
  312. #endif
  313.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  314.  
  315.     /* render the playfield */
  316.     memset(atarigen_pf2_visit, 0, 64*64);
  317. #if DEBUG_VIDEO
  318.     if (show_colors != 1)
  319. #endif
  320.     atarigen_pf2_process(pf2_render_callback, bitmap, &Machine->drv->visible_area);
  321.  
  322.     /* render the motion objects */
  323.     atarigen_mo_process(mo_render_callback, bitmap);
  324.  
  325.     /* update onscreen messages */
  326.     atarigen_update_messages();
  327. }
  328.  
  329.  
  330.  
  331. /*************************************
  332.  *
  333.  *    Palette management
  334.  *
  335.  *************************************/
  336.  
  337. static const UINT8 *update_palette(void)
  338. {
  339.     UINT16 mo_map[16], pf_map[48];
  340.     int i, j;
  341.  
  342.     /* reset color tracking */
  343.     memset(mo_map, 0, sizeof(mo_map));
  344.     memset(pf_map, 0, sizeof(pf_map));
  345.     palette_init_used_colors();
  346.     
  347.     /* update color usage for the playfields */
  348.     atarigen_pf_process(pf_color_callback, pf_map, &Machine->drv->visible_area);
  349.     atarigen_pf2_process(pf2_color_callback, pf_map, &Machine->drv->visible_area);
  350.  
  351.     /* update color usage for the mo's */
  352.     atarigen_mo_process(mo_color_callback, mo_map);
  353.  
  354.     /* rebuild the playfield palettes */
  355.     for (i = 0; i < 48; i++)
  356.     {
  357.         UINT16 used = pf_map[i];
  358.         if (used)
  359.         {
  360.             if (i < 16)
  361.                 palette_used_colors[0x000 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  362.             else if (used & 0x0001)
  363.                 palette_used_colors[0x000 + i * 16 + 0] = PALETTE_COLOR_USED;
  364.             for (j = 1; j < 16; j++)
  365.                 if (used & (1 << j))
  366.                     palette_used_colors[0x000 + i * 16 + j] = PALETTE_COLOR_USED;
  367.         }
  368.     }
  369.  
  370.     /* rebuild the motion object palette */
  371.     for (i = 0; i < 16; i++)
  372.     {
  373.         UINT16 used = mo_map[i];
  374.         if (used)
  375.         {
  376.             palette_used_colors[0x100 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  377.             for (j = 1; j < 16; j++)
  378.                 if (used & (1 << j))
  379.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  380.         }
  381.     }
  382.  
  383.     return palette_recalc();
  384. }
  385.  
  386.  
  387.  
  388. /*************************************
  389.  *
  390.  *    Playfield palette
  391.  *
  392.  *************************************/
  393.  
  394. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  395. {
  396.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  397.     UINT16 *colormap = param;
  398.     int x, y;
  399.     
  400.     /* standard loop over tiles */
  401.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  402.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  403.         {
  404.             int offs = x * 64 + y;
  405.             int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  406.             int data2 = READ_WORD(&atarigen_playfieldram_color[offs * 2]);
  407.             int code = data1 & 0x7fff;
  408.             int color = 0x20 + (data2 & 0x0f);
  409.  
  410.             /* mark the colors used by this tile */
  411.             colormap[color] |= usage[code];
  412.             
  413.             /* also mark unvisited tiles dirty */
  414.             if (!atarigen_pf_visit[offs]) atarigen_pf_dirty[offs] = 1;
  415.         }
  416. }
  417.  
  418.  
  419. static void pf2_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  420. {
  421.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  422.     UINT16 *colormap = param;
  423.     int x, y;
  424.     
  425.     /* standard loop over tiles */
  426.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  427.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  428.         {
  429.             int offs = x * 64 + y;
  430.             int data1 = READ_WORD(&atarigen_playfield2ram[offs * 2]);
  431.             int data2 = READ_WORD(&atarigen_playfieldram_color[offs * 2]);
  432.             int code = data1 & 0x7fff;
  433.             int color = (data2 >> 8) & 0x0f;
  434.  
  435.             /* mark the colors used by this tile */
  436.             colormap[color] |= usage[code];
  437.             
  438.             /* also mark unvisited tiles dirty */
  439.             if (!atarigen_pf2_visit[offs]) atarigen_pf2_dirty[offs] = 1;
  440.         }
  441. }
  442.  
  443.  
  444.  
  445. /*************************************
  446.  *
  447.  *    Playfield rendering
  448.  *
  449.  *************************************/
  450.  
  451. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  452. {
  453.     const struct GfxElement *gfx = Machine->gfx[0];
  454.     struct osd_bitmap *bitmap = param;
  455.     int x, y;
  456.  
  457.     /* standard loop over tiles */
  458.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  459.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  460.         {
  461.             int offs = x * 64 + y;
  462.             
  463.             /* update only if dirty */
  464.             if (atarigen_pf_dirty[offs])
  465.             {
  466.                 int data1 = READ_WORD(&atarigen_playfieldram[offs * 2]);
  467.                 int data2 = READ_WORD(&atarigen_playfieldram_color[offs * 2]);
  468.                 int color = 0x20 + (data2 & 0x0f);
  469.                 int code = data1 & 0x7fff;
  470.                 int hflip = data1 & 0x8000;
  471.                 
  472.                 drawgfx(atarigen_pf_bitmap, gfx, code, color, hflip, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  473.                 atarigen_pf_dirty[offs] = 0;
  474.  
  475. #if DEBUG_VIDEO
  476.                 if (show_colors == 1)
  477.                 {
  478.                     drawgfx(atarigen_pf_bitmap, Machine->uifont, "0123456789ABCDEF"[color - 0x20], 1, 0, 0, 8 * x + 0, 8 * y, 0, TRANSPARENCY_PEN, 0);
  479.                     drawgfx(atarigen_pf_bitmap, Machine->uifont, "0123456789ABCDEF"[color - 0x20], 1, 0, 0, 8 * x + 2, 8 * y, 0, TRANSPARENCY_PEN, 0);
  480.                     drawgfx(atarigen_pf_bitmap, Machine->uifont, "0123456789ABCDEF"[color - 0x20], 0, 0, 0, 8 * x + 1, 8 * y, 0, TRANSPARENCY_PEN, 0);
  481.                 }
  482. #endif
  483.             }
  484.             
  485.             /* track the tiles we've visited */
  486.             atarigen_pf_visit[offs] = 1;
  487.         }
  488.  
  489.     /* then blast the result */
  490.     x = -state->hscroll;
  491.     y = -state->vscroll;
  492.     copyscrollbitmap(bitmap, atarigen_pf_bitmap, 1, &x, 1, &y, clip, TRANSPARENCY_NONE, 0);
  493. }
  494.  
  495.  
  496. static void pf2_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  497. {
  498.     const struct GfxElement *gfx = Machine->gfx[0];
  499.     struct osd_bitmap *bitmap = param;
  500.     int x, y;
  501.  
  502.     /* standard loop over tiles */
  503.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  504.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  505.         {
  506.             int offs = x * 64 + y;
  507.             
  508.             /* update only if dirty */
  509.             if (atarigen_pf2_dirty[offs])
  510.             {
  511.                 int data1 = READ_WORD(&atarigen_playfield2ram[offs * 2]);
  512.                 int data2 = READ_WORD(&atarigen_playfieldram_color[offs * 2]);
  513.                 int color = (data2 >> 8) & 0x0f;
  514.                 int code = data1 & 0x7fff;
  515.                 int hflip = data1 & 0x8000;
  516.                 
  517.                 drawgfx(atarigen_pf2_bitmap, gfx, code, color, hflip, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  518.                 atarigen_pf2_dirty[offs] = 0;
  519.  
  520. #if DEBUG_VIDEO
  521.                 if (show_colors == 2)
  522.                 {
  523.                     drawgfx(atarigen_pf2_bitmap, Machine->uifont, "0123456789ABCDEF"[color], 1, 0, 0, 8 * x + 0, 8 * y, 0, TRANSPARENCY_PEN, 0);
  524.                     drawgfx(atarigen_pf2_bitmap, Machine->uifont, "0123456789ABCDEF"[color], 1, 0, 0, 8 * x + 2, 8 * y, 0, TRANSPARENCY_PEN, 0);
  525.                     drawgfx(atarigen_pf2_bitmap, Machine->uifont, "0123456789ABCDEF"[color], 0, 0, 0, 8 * x + 1, 8 * y, 0, TRANSPARENCY_PEN, 0);
  526.                 }
  527. #endif
  528.             }
  529.             
  530.             /* track the tiles we've visited */
  531.             atarigen_pf2_visit[offs] = 1;
  532.         }
  533.  
  534.     /* then blast the result */
  535.     x = -state->hscroll;
  536.     y = -state->vscroll;
  537.     copyscrollbitmap(bitmap, atarigen_pf2_bitmap, 1, &x, 1, &y, clip, TRANSPARENCY_PEN, palette_transparent_pen);
  538. }
  539.  
  540.  
  541.  
  542. /*************************************
  543.  *
  544.  *    Playfield overrendering
  545.  *
  546.  *************************************/
  547.  
  548. static void pf2_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  549. {
  550.     const struct pf_overrender_data *overrender_data = param;
  551.     struct osd_bitmap *bitmap = overrender_data->bitmap;
  552.     int min_color = overrender_data->mo_priority ? 1 : 0;
  553.     const struct GfxElement *gfx = Machine->gfx[0];
  554.     int x, y;
  555.  
  556.     /* standard loop over tiles */
  557.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  558.     {
  559.         int sx = (8 * x - state->hscroll) & 0x1ff;
  560.         if (sx >= XDIM) sx -= 0x200;
  561.  
  562.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  563.         {
  564.             int offs = x * 64 + y;
  565.             int data2 = READ_WORD(&atarigen_playfieldram_color[offs * 2]);
  566.             int color = (data2 >> 8) & 0x0f;
  567.             
  568.             if (color >= min_color)
  569.             {
  570.                 int data1 = READ_WORD(&atarigen_playfield2ram[offs * 2]);
  571.                 int code = data1 & 0x7fff;
  572.                 int hflip = data1 & 0x8000;
  573.  
  574.                 int sy = (8 * y - state->vscroll) & 0x1ff;
  575.                 if (sy >= YDIM) sy -= 0x200;
  576.             
  577.                 drawgfx(bitmap, gfx, code, color, hflip, 0, sx, sy, clip, TRANSPARENCY_PEN, 0);
  578.             }
  579.         }
  580.     }
  581. }
  582.  
  583.  
  584.  
  585. /*************************************
  586.  *
  587.  *    Motion object palette
  588.  *
  589.  *************************************/
  590.  
  591. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  592. {
  593.     const unsigned int *usage = Machine->gfx[1]->pen_usage;
  594.     UINT16 *colormap = param;
  595.     int code = data[1] & 0x7fff;
  596.     int color = data[2] & 0x000f;
  597.     int hsize = ((data[3] >> 4) & 7) + 1;
  598.     int vsize = (data[3] & 7) + 1;
  599.     int tiles = hsize * vsize;
  600.     UINT16 temp = 0;
  601.     int i;
  602.  
  603.     for (i = 0; i < tiles; i++)
  604.         temp |= usage[code++];
  605.     colormap[color] |= temp;
  606. }
  607.  
  608.  
  609.  
  610. /*************************************
  611.  *
  612.  *    Motion object rendering
  613.  *
  614.  *************************************/
  615.  
  616. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  617. {
  618.     struct GfxElement *gfx = Machine->gfx[1];
  619.     struct pf_overrender_data overrender_data;
  620.     struct osd_bitmap *bitmap = param;
  621.     struct rectangle pf_clip;
  622.  
  623.     /* extract data from the various words */
  624.     int hflip = data[1] & 0x8000;
  625.     int code = data[1] & 0x7fff;
  626.     int xpos = (data[2] >> 7) - atarigen_video_control_state.sprite_xscroll;
  627.     int priority = (data[2] >> 3) & 1;
  628.     int color = data[2] & 0x000f;
  629.     int ypos = -(data[3] >> 7) - atarigen_video_control_state.sprite_yscroll;
  630.     int hsize = ((data[3] >> 4) & 7) + 1;
  631.     int vsize = (data[3] & 7) + 1;
  632.  
  633.     /* adjust for height */
  634.     ypos -= vsize * 8;
  635.  
  636.     /* adjust the final coordinates */
  637.     xpos &= 0x1ff;
  638.     ypos &= 0x1ff;
  639.     if (xpos >= XDIM) xpos -= 0x200;
  640.     if (ypos >= YDIM) ypos -= 0x200;
  641.  
  642.     /* determine the bounding box */
  643.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  644.  
  645.     /* draw an instance of the object in all transparent pens */
  646.     atarigen_mo_draw_transparent_8x8(bitmap, gfx, code, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  647.  
  648.     /* and then draw it normally on the temp bitmap */
  649.     atarigen_mo_draw_8x8(atarigen_pf_overrender_bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_NONE, 0);
  650.  
  651.     /* overrender the playfield on top of that that */
  652.     overrender_data.mo_priority = priority;
  653.     overrender_data.bitmap = atarigen_pf_overrender_bitmap;
  654.     atarigen_pf2_process(pf2_overrender_callback, &overrender_data, &pf_clip);
  655.  
  656.     /* finally, copy this chunk to the real bitmap */
  657.     copybitmap(bitmap, atarigen_pf_overrender_bitmap, 0, 0, 0, 0, &pf_clip, TRANSPARENCY_THROUGH, palette_transparent_pen);
  658.  
  659. #if DEBUG_VIDEO
  660.     if (show_colors)
  661.     {
  662.         int tx = (pf_clip.min_x + pf_clip.max_x) / 2 - 3;
  663.         int ty = (pf_clip.min_y + pf_clip.max_y) / 2 - 4;
  664.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx - 2, ty - 2, 0, TRANSPARENCY_NONE, 0);
  665.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx + 2, ty - 2, 0, TRANSPARENCY_NONE, 0);
  666.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx - 2, ty + 2, 0, TRANSPARENCY_NONE, 0);
  667.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx + 2, ty + 2, 0, TRANSPARENCY_NONE, 0);
  668.         drawgfx(bitmap, Machine->uifont, "0123456789ABCDEF"[priority], 0, 0, 0, tx, ty, 0, TRANSPARENCY_NONE, 0);
  669.     }
  670. #endif
  671. }
  672.  
  673.  
  674.  
  675. /*************************************
  676.  *
  677.  *    Debugging
  678.  *
  679.  *************************************/
  680.  
  681. #if DEBUG_VIDEO
  682.  
  683. static void debug(void)
  684. {
  685.     int new_show_colors;
  686.     
  687.     new_show_colors = (keyboard_pressed(KEYCODE_LSHIFT)) ? 1 : keyboard_pressed(KEYCODE_RSHIFT) ? 2 : 0;
  688.     if (new_show_colors != show_colors)
  689.     {
  690.         show_colors = new_show_colors;
  691.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 2);
  692.         memset(atarigen_pf2_dirty, 0xff, atarigen_playfieldram_size / 2);
  693.     }
  694.  
  695.     special_pen = -1;
  696.     if (keyboard_pressed(KEYCODE_Q)) special_pen = 0;
  697.     if (keyboard_pressed(KEYCODE_W)) special_pen = 1;
  698.     if (keyboard_pressed(KEYCODE_E)) special_pen = 2;
  699.     if (keyboard_pressed(KEYCODE_R)) special_pen = 3;
  700.     if (keyboard_pressed(KEYCODE_T)) special_pen = 4;
  701.     if (keyboard_pressed(KEYCODE_Y)) special_pen = 5;
  702.     if (keyboard_pressed(KEYCODE_U)) special_pen = 6;
  703.     if (keyboard_pressed(KEYCODE_I)) special_pen = 7;
  704.  
  705.     if (keyboard_pressed(KEYCODE_A)) special_pen = 8;
  706.     if (keyboard_pressed(KEYCODE_S)) special_pen = 9;
  707.     if (keyboard_pressed(KEYCODE_D)) special_pen = 10;
  708.     if (keyboard_pressed(KEYCODE_F)) special_pen = 11;
  709.     if (keyboard_pressed(KEYCODE_G)) special_pen = 12;
  710.     if (keyboard_pressed(KEYCODE_H)) special_pen = 13;
  711.     if (keyboard_pressed(KEYCODE_J)) special_pen = 14;
  712.     if (keyboard_pressed(KEYCODE_K)) special_pen = 15;
  713.     
  714.     if (keyboard_pressed(KEYCODE_9))
  715.     {
  716.         static int count;
  717.         char name[50];
  718.         FILE *f;
  719.         int i;
  720.  
  721.         while (keyboard_pressed(KEYCODE_9)) { }
  722.  
  723.         sprintf(name, "Dump %d", ++count);
  724.         f = fopen(name, "wt");
  725.  
  726.         fprintf(f, "\n\nAlpha Palette:\n");
  727.         for (i = 0x000; i < 0x100; i++)
  728.         {
  729.             fprintf(f, "%04X ", READ_WORD(&paletteram[i*2]));
  730.             if ((i & 15) == 15) fprintf(f, "\n");
  731.         }
  732.  
  733.         fprintf(f, "\n\nMotion Object Palette:\n");
  734.         for (i = 0x100; i < 0x200; i++)
  735.         {
  736.             fprintf(f, "%04X ", READ_WORD(&paletteram[i*2]));
  737.             if ((i & 15) == 15) fprintf(f, "\n");
  738.         }
  739.  
  740.         fprintf(f, "\n\nPlayfield Palette:\n");
  741.         for (i = 0x200; i < 0x400; i++)
  742.         {
  743.             fprintf(f, "%04X ", READ_WORD(&paletteram[i*2]));
  744.             if ((i & 15) == 15) fprintf(f, "\n");
  745.         }
  746.  
  747.         fprintf(f, "\n\nMotion Object Config:\n");
  748.         for (i = 0x00; i < 0x40; i++)
  749.         {
  750.             fprintf(f, "%04X ", READ_WORD(&atarigen_playfieldram[0xf00 + i*2]));
  751.             if ((i & 15) == 15) fprintf(f, "\n");
  752.         }
  753.  
  754.         fprintf(f, "\n\nMotion Object SLIPs:\n");
  755.         for (i = 0x00; i < 0x40; i++)
  756.         {
  757.             fprintf(f, "%04X ", READ_WORD(&atarigen_playfieldram[0xf80 + i*2]));
  758.             if ((i & 15) == 15) fprintf(f, "\n");
  759.         }
  760.  
  761.         fprintf(f, "\n\nMotion Objects\n");
  762.         for (i = 0; i < 0x400; i++)
  763.         {
  764.             UINT16 *data = (UINT16 *)&atarigen_spriteram[i*8];
  765.             int code = data[1] & 0x7fff;
  766.             int hsize = ((data[3] >> 4) & 7) + 1;
  767.             int vsize = (data[3] & 7) + 1;
  768.             int xpos = (data[2] >> 7);
  769.             int ypos = (data[3] >> 7) - vsize * 8;
  770.             int color = data[2] & 15;
  771.             int hflip = data[3] & 0x0008;
  772.             fprintf(f, "   Object %03X: L=%03X P=%04X C=%X X=%03X Y=%03X W=%d H=%d F=%d LEFT=(%04X %04X %04X %04X)\n",
  773.                     i, data[0] & 0x3ff, code, color, xpos & 0x1ff, ypos & 0x1ff, hsize, vsize, hflip,
  774.                     data[0] & 0xfc00, data[1] & 0x0000, data[2] & 0x0070, data[3] & 0x0000);
  775.         }
  776.  
  777.         fprintf(f, "\n\nPlayfield 1 dump\n");
  778.         for (i = 0; i < atarigen_playfieldram_size / 2; i++)
  779.         {
  780.             fprintf(f, "%X%04X ", READ_WORD(&atarigen_playfieldram_color[i*2]) & 0xff, READ_WORD(&atarigen_playfieldram[i*2]));
  781.             if ((i & 63) == 63) fprintf(f, "\n");
  782.         }
  783.  
  784.         fprintf(f, "\n\nPlayfield 2 dump\n");
  785.         for (i = 0; i < atarigen_playfield2ram_size / 2; i++)
  786.         {
  787.             fprintf(f, "%X%04X ", (READ_WORD(&atarigen_playfieldram_color[i*2]) >> 8) & 0xff, READ_WORD(&atarigen_playfield2ram[i*2]));
  788.             if ((i & 63) == 63) fprintf(f, "\n");
  789.         }
  790.  
  791.         fprintf(f, "\n\nAlpha dump\n");
  792.         for (i = 0; i < atarigen_alpharam_size / 2; i++)
  793.         {
  794.             fprintf(f, "%04X ", READ_WORD(&atarigen_alpharam[i*2]));
  795.             if ((i & 63) == 63) fprintf(f, "\n");
  796.         }
  797.  
  798.         fclose(f);
  799.     }
  800. }
  801.  
  802. #endif
  803.